package itsen.com.bduidemo.modle.event.scroller;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.widget.Scroller;

import java.util.ArrayList;
import java.util.List;

import itsen.com.bduidemo.lib.tool.LogTool;
import itsen.com.bduidemo.lib.util.DensityUtils;

/**
 * Created by zds
 * Created time 2018/3/19 14:22
 * Description:DNui
 * Version: V 1.0
 */

public class ScrollerFlingView extends View {
    /**
     * 画笔
     */
    private Paint mPaint;
    /**
     * 颜色
     */
    private int mCloor = 0x666666;
    /**
     * 条目高度
     */
    private int mItemHeight = 50;
    /**
     * scroller
     */
    private Scroller mScroller;
    /**
     * 数字大小
     */
    private int mTextSize = 20;
    /**
     * Y轴Scroll滚动的位移
     */
    private int mScrollOffsetY = 0;
    /**
     * 最大可以Fling的距离
     */
    private int mMaxFlingY, mMinFlingY;
    private float mLastY;
    private float mRawY;
    /**
     * 速度
     */
    private VelocityTracker mTracker;
    /**
     * 滚轮滑动时的最小/最大速度
     */
    private int mMinimumVelocity = 50, mMaximumVelocity = 12000;
    private List<String> list;

    /**
     * 手指停止滑动
     */
    private boolean mIsAbortScroller;

    public ScrollerFlingView(Context context) {
        this(context, null);

    }

    public ScrollerFlingView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);

    }

    public ScrollerFlingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // 第一步，创建Scroller的实例
        mScroller = new Scroller(context);
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setColor(Color.RED);
        mItemHeight = DensityUtils.dp2px(50);
        mTextSize = DensityUtils.dp2px(20);
        mPaint.setTextSize(mTextSize);
        mPaint.setTextAlign(Paint.Align.CENTER);
        list = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            list.add("i:" + i);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int i = 0; i < list.size(); i++) {
            canvas.drawText(list.get(i), getWidth() / 2, i * mItemHeight, mPaint);
        }
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mTracker == null) {
            mTracker = VelocityTracker.obtain();
        }
        mTracker.addMovement(event);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (!mScroller.isFinished()) {
                    mScroller.abortAnimation();
                    mIsAbortScroller = true;
                } else {
                    mIsAbortScroller = false;
                }
                mLastY = event.getRawY();
                mTracker.clear();
                break;
            case MotionEvent.ACTION_MOVE:
                mRawY = event.getRawY();
                int sy = (int) (mLastY - mRawY);
                LogTool.e("SY:"+sy);
                mScrollOffsetY += sy;
                scrollBy(0, sy);
                mLastY = mRawY;
                break;
            case MotionEvent.ACTION_UP:
                mTracker.computeCurrentVelocity(1000, mMaximumVelocity);
                int velocity = (int) mTracker.getYVelocity();
                if (Math.abs(velocity) > mMinimumVelocity) {
                    mScroller.fling(0, mScrollOffsetY, 0, velocity,
                            0, 0, mMinFlingY, mMaxFlingY);
                }

                if (mScroller.getFinalY() > mMaxFlingY) {
                    mScroller.setFinalY(mMaxFlingY);
                } else if (mScroller.getFinalY() < mMinFlingY) {
                    mScroller.setFinalY(mMinFlingY);
                }

                break;
            default:
                break;
        }
        return true;
    }

    @Override
    public void computeScroll() {
        // 第三步，重写computeScroll()方法，并在其内部完成平滑滚动的逻辑
        if (mScroller.computeScrollOffset()) {
            mScrollOffsetY = mScroller.getCurrY();
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate();
        }
    }

    /**
     * 计算Fling极限
     * 如果为Cyclic模式则为Integer的极限值，如果正常模式，则为一整个数据集的上下限。
     */
    private void computeFlingLimitY() {
        mMinFlingY =  - mItemHeight * (list.size());
        mMaxFlingY =  0;
    }

    /**
     * 是否循环读取
     */
    private boolean mIsCyclic = true;

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        computeFlingLimitY();
    }
}
